var messageWebSocket = function(receipt, bind, setFunc)
{
	var main = function()
	{
		// var ws;							// message连接
		// var ID = "";					// 用户登录ID
		// var name = "";					// 用户昵称
		// var time = "";					// 用户登录时间
		// var self = this;
		// var open = false;				// 与后台基础信息是否已交换完成
		// var proPage = 0;				// protected消息页码
		// var status = false;				// 用户登录状态
		// var errorBreak = true;			// 连接异常断开标志
		// var receiveList = [];			// 当与后台基础信息为交换完成却接收到信息，则存储在改数组
		
		// // 对象赋值函数
		// var setFunc = setFunc || function(obj, name, value){
		// 	obj[name] = value;
		// };
		
		// var msgList = bind.msgList || {};		// 消息缓存区
		// var userList = bind.userList || {};		// 用户缓存区
		// var pubList = bind.publicList || [];
		// var priMsg = bind.privateMsg || {};
		// var proList = bind.protectedList || [];
		
		// this.debug = false;
		
		// // 连接打开时触发
		// this.onOpen = function(){};
		
		// // 连接关闭时触发
		// this.onClose = function(){};
		
		// // 新消息出现时触发
		// this.onNewMsg = function(){
		// 	log("message有新消息到达！", "debug", self.debug);
		// };
		
		// this.getTime = function()
		// {
		// 	return time;
		// }
		
		// // 主动关闭连接
		// this.close = function()
		// {
		// 	ws.close();
		// };
		
		// // 获取当前登录ID
		// this.getID = function()
		// {
		// 	return ID;
		// };
		
		// // 获取缓存中的ID
		// this.getId = function(ID)
		// {
		// 	return ub.getId(ID);
		// }
		
		// // 获取当前登录用户昵称
		// this.getName = function()
		// {
		// 	return name;
		// };
		
		// // 获取登录状态
		// this.getLogin = function()
		// {
		// 	return status;
		// }
		
		// message系统登录
		// this.login = function(username, password, code, callback)
		// {
		// 	if(status)return;
		// 	var request = {
		// 		method: "post",
		// 		url: "forum/login_webAjaxCheck.lyx", 
		// 		data:
		// 		{
		// 			"username": username,
		// 			"password": password,
		// 			"imgCode": code
		// 		}
		// 	};
		// 	ajax(request, function(xhr, response){
		// 		callback(response);
		// 		if(response != "验证码错误" && response != "用户不存在或者密码错误")
		// 		{
		// 			try
		// 			{
		// 				var json = JSON.parse(response);
		// 				ID = json.ID;
		// 				name = json.name;
		// 				openWs();
		// 			}
		// 			catch(error){}
		// 		}
		// 	});
		// }
		
		// cookie登录
		this.cookieLogin = function()
		{
			ajax({
				url: "forum/login_cookieLoginChexk.lyx"
			}, function(xhr, res){
				try
				{
					var json = JSON.parse(res);
					ID = json.ID;
					name = json.name;
					openWs();
				}
				catch(error)
				{
					find.loginWindow = false;
				}
			});
		}
		
		// // 注销登录
		// this.logout = function(callback)
		// {
		// 	errorBreak = false;
		// 	ajax({
		// 		method: "post",
		// 		url: "forum/login_webAjaxExit.lyx"
		// 	}, function(){
		// 		name = "";
		// 		status = false;
		// 		callback && callback();
		// 	});
		// }
		
		// 打开webSocket连接
		// var openWs = function()
		// {
		// 	if(ws != null)
		// 	{
		// 		ws.open();
		// 		return;
		// 	}
		// 	ws = webSocket("forum/message");
		// 	ws.onOpen = function()
		// 	{
		// 		log("message连接打开....", "debug", self.debug);
		// 		self.onOpen(ID, name);
		// 	};
		// 	ws.onMessage = function(json)
		// 	{
		// 		if(open || json.type == "open")
		// 		{
		// 			// self参数为方便测试而添加，可去除
		// 			call[json.type](json, self);
		// 		}
		// 		else
		// 		{
		// 			receiveList.unshift(json);
		// 		}
		// 	}
		// 	ws.onClose = function()
		// 	{
		// 		time = "";
		// 		status = false;
		// 		self.onClose();
		// 		log("message连接关闭....", "debug", self.debug);
		// 		if(errorBreak)
		// 		{
		// 			am.alert({
		// 				msg: "当前账号已掉线！",
		// 				msgStyle: {
		// 					height: 60,
		// 					width: 240
		// 				},
		// 				ok: {
		// 					value: "重新登录",
		// 					func: function()
		// 					{
		// 						log("重新登录");
		// 						openWs();
		// 					}	
		// 				},
		// 				cancel: {
		// 					value: "取消",
		// 					func: function()
		// 					{
		// 						log("取消登录");
		// 					}
		// 				}
		// 			});
		// 		}
		// 	};
		// }
		// // 获取当前登录人信息（不包含学生信息）
		// this.getLoginInfo = function()
		// {
		// 	ws.send({
		// 		type: "stuInfo"
		// 	});
		// };
		
		// // 发送私聊信息
		// this.sendMsg = function(receiveID, content)
		// {
		// 	if(content.length == 0)
		// 	{
		// 		return "消息不可为空！";
		// 	}
		// 	else if(content.length > 6000)
		// 	{
		// 		return "消息过长！";
		// 	}
		// 	else
		// 	{
		// 		ws.send({
		// 			type: "msg",
		// 			ID: receiveID,
		// 			content: content
		// 		});
		// 	}
		// 	return true;
		// };
		
		// 获取更多消息
		// this.getMoreMsg = function(type, page, id)
		// {
		// 	var msg = {
		// 		page: page,
		// 		time: time
		// 	};
		// 	switch(type)
		// 	{
		// 		case "public":
		// 			msg.id = id;
		// 			msg.type = "morePub";
		// 			break;
		// 		case "protected":
		// 			msg.type = "morePro";
		// 			if(proPage == "noMore")
		// 			{
		// 				receipt.morePro(false);
		// 				return false;
		// 			}
		// 			msg.page = proPage;
		// 			break;
		// 		case "private":
		// 			msg.ID = id;
		// 			msg.type = "morePri";
		// 			break;
		// 	}
		// 	ws.send(msg);
		// 	return true;
		// };
		
		// // 更新用户信息
		// this.updata = function(nickname, birth)
		// {
		// 	var regex = /^[A-Za-z0-9/_\-\u4e00-\u9fa5]{3,10}$/;
		// 	if(nickname != "" && regex.test(nickname))
		// 	{
		// 		ws.send({
		// 			type: "updata",
		// 			name: nickname,
		// 			birth: birth
		// 		});
		// 		return true;
		// 	}
		// 	else
		// 	{
		// 		return "昵称最少3个字符最多10个字符，不可包含特殊符号";
		// 	}
		// };
		
		// // 根据ID获取用户基本信息
		// this.getUser = function(idList)
		// {
		// 	ws.send({
		// 		type: "getUser",
		// 		idList: idList
		// 	});
		// };
		
		// // 根据id获取消息
		// this.getMsg = function(idList)
		// {
		// 	ws.send({
		// 		type: "getMsg",
		// 		idList: idList
		// 	});
		// }
		
		// // 标记信息已读
		// this.read = function(id)
		// {
		// 	ws.send({
		// 		id: id,
		// 		type: "read"
		// 	});
		// };
		
		// // 删除消息
		// this.delMsg = function(id)
		// {
		// 	// 根据id计算消息类型，返回时附带type
		// 	ws.send({
		// 		id: id,
		// 		type: "del"
		// 	});
		// };
		
		// // 获取以当前时间节点为基准的第一页评论
		// this.getComment = function(id)
		// {
		// 	ws.send({
		// 		id: id,
		// 		type: "getComment"
		// 	});
		// };
		
		// // 更新评论
		// this.getNewComment = function(id, time)
		// {
		// 	ws.send({
		// 		id: id,
		// 		time: time,
		// 		type: "newComment"
		// 	});
		// };
		
		// // 提交评论
		// this.comment = function(id, msg)
		// {
		// 	if(msg.trim() == "")
		// 	{
		// 		return "内容不能为空！";
		// 	}
		// 	else if(stringLength(msg)/2 > 144)
		// 	{
		// 		return "最多评论144个字！";
		// 	}
		// 	else
		// 	{
		// 		ws.send({
		// 			id: id,
		// 			msg: msg,
		// 			type: "comment"
		// 		});
		// 		return true;
		// 	}
		// };
		
		// 文件传输（待完善）
		this.upload = function(file)
		{
			var reader = new FileReader();
			reader.readAsArrayBuffer(file);
			reader.onload = function loaded(evt)
			{
				var binaryString = evt.target.result;
				ws.sendImg({
					type: "file",
					content: binaryString
				});
			}
		}
		
		// // msg分类处理
		// var msgClassify =
		// {
		// 	"public": function(msg)
		// 	{
		// 		var obj = {
		// 			list: [],
		// 			next: true,
		// 			message: msg,
		// 			request: false
		// 		};
		// 		var i = 0;
		// 		while(i < pubList.length)
		// 		{
		// 			var items = pubList[i].message;
		// 			if(msg.id > items.id)
		// 			{
		// 				break;
		// 			}
		// 			i ++;
		// 		}
		// 		pubList.splice(i, 0, obj);
		// 	},
		// 	"protected": function(msg)
		// 	{
		// 		var i = 0;
		// 		while(i < proList.length)
		// 		{
		// 			var items = proList[i].message;
		// 			if(msg.id > items.id)
		// 			{
		// 				break;
		// 			}
		// 			i ++;
		// 		}
		// 		proList.splice(i, 0, msg);
		// 	},
		// 	"private": function(msg)
		// 	{
		// 		var user = msg.sendID.username == ID ? msg.receiveID : msg.sendID;
		// 		if(typeof priMsg[user.username] == "undefined")
		// 		{
		// 			priMsg[user.username] = {
		// 				user: user,
		// 				list: [msg]
		// 			};
		// 		}
		// 		else
		// 		{
		// 			var list = priMsg[user.username].list;
		// 			var i = 0;
		// 			while(i < list.length)
		// 			{
		// 				if(msg.id < list[i].id)
		// 				{
		// 					break;
		// 				}
		// 				i ++;
		// 			}
		// 			list.splice(i, 0, msg);
		// 		}
		// 	}
		// }
		
		// 回执部分
		var call = {
			read: receipt.read ||  function(){},
			updata: receipt.updata || function(){},
			comment: receipt.comment || function(){},
			stuInfo: receipt.stuInfo || function(){},
			morePri: receipt.morePri || function(){},
			getComment: receipt.getComment || function(){},
			newPubMsg: receipt.newPubMsg || function(){},
			msg: function(json)
			{
				for(var i = 0; i < json.list.length; i++)
				{
					var msg = json.list[i];
					msg.unRead = msg.unRead == 1;
					msg.sendID = ub.setList(msg.sendID);
					msg.receiveID = ub.setList(msg.receiveID);
					msgClassify[msg.type](msg);
					setFunc(msgList, msg.id, msg);
					if(new Date(msg.time) - new Date(time) >= 0 && msg.sendID != ID)
					{
						self.onNewMsg(msg);
					}
					receipt.msg || receipt.msg(msg);
				}
				ub.sendList();
			},
			online: function(json)
			{
				for(i in json.online)
				{
					if(typeof userList[i] != "undefined")
					{
						userList[i].online = json.online[i];
					}
				}
			},
			getMsg: function(json)
			{
				mb.setModel(json.map);
			},
			getUser: function(json)
			{
				ub.setModel(json.map);
			},
			open: function(json)
			{
				if(ID != json.ID)
				{
					ws.close();
					return;
				}
				open = true;
				status = true;
				time = json.time;
				while(receiveList.length != 0)
				{
					var json = receiveList.pop();
					call[json.type](json, self);
				}
			},
			del: function(json)
			{
				if(json.idList)
				{
					for(var i = 0; i < json.idList; i ++)
					{
						mb.del(json.idList[i]);
					}
					receipt.delPub(json);
				}
				else
				{
					mb.del(json.id);
					for(var i = 0; i < proList.lenght; i ++)
					{
						if(json.id == proList[i].message.id)
						{
							proList.splice(i, 1);
						}
					}
					receipt.delPro(json);
				}
			},
			morePro: function(json)
			{
				if(json.page)
				{
					proPage ++;
				}
				else
				{
					proPage = "noMore";
				}
				receipt.morePro = receipt.morePro || function(){};
				receipt.morePro(json.page != "noMore");
			},
			conflict: function()
			{
				alert("该用户在其他地方登陆！");
			}
		};
		
		var ub = new Buffer(userList, {
			online: "",
			sex: "加载中...",
			username: "加载中...",
			nickname: "加载中...",
			avatarWay: ""
		}, this.getUser, setFunc);
		
		var mb = new Buffer(msgList, {
			id: "加载中...",
			type: "加载中...",
			time: "加载中...",
			unRead: "加载中...",
			sendID: "加载中...",
			message: "加载中...",
			receiveID: "加载中..."
		}, this.getMsg, setFunc);

		mb.delModel = function(buffer, id)
		{
			buffer.id = null;
		}
	}
	return new main();
}





define(["base", "ajax"], function(_, ajax, Lyx){

	"use strict"

	// 用户尚未登录完毕时接受的消息
	var receiveList = new Lyx.queue();

	// 用户信息
	var user = {
		ID: "",		// 用户id
		name: "",	// 用户昵称
		time: ""	// 用户登录时间
	};

	// 消息池
	var msgPool;

	// 用户池
	var userPool;

	var pubList, priMsg, proList;

	// 登录状态
	var status = false;

	// 消息分类处理
	var msgClassify = 
	{
		public: function(msg)
		{
			var obj = {
				list: [],
				next: true,
				message: msg,
				request: false
			};
			var index = pubList.lenght;
			while(index -- != 0)
			{
				var items = pubList[index].message;
				if(msg.id < items.id)
				{
					break;
				}
			}
			pubList.splice(index, 0, obj);
		},
		protected: function(msg)
		{
			var index = proList.lenght;
			while(index-- != 0)
			{
				var items = proList[index].message;
				if(msg.id < items.id)
				{
					break;
				}
			}
			proList.splice(index, 0, msg);
		},
		private: function(msg)
		{
			var user = msg.sendID.username == "ID" ? msg.receiveID : msg.sendID;
			if(Lyx.isUndefined(priMsg[user.username]))
			{
				priMsg[user.username] = {
					user: user,
					list: [msg]
				};
			}
			else
			{
				var list = priMsg[user.username].list;
				var index = list.lenght;
				while(index -- != 0)
				{
					if(msg.id > list[index].id)
					{
						break;
					}
				}
				list.splice(index, 0, msg);
			}
		}
	}

	/**
	 * @param {function} callback 服务器消息回调
	 * @param {object} data 存储对象
	 * @param {function} setFunc 设置对象属性的方法
	 */
    var msg = function(callback, data, setFunc)
    {
		setFunc = setFunc || function(obj, name, value)
		{
			obj[name] = value;
		};

		// 创建用户池
		userPool = new _.pool(data.userPool || {}, {
			online: "",
			sex: "加载中...",
			username: "加载中...",
			nickname: "加载中...",
			avatarWay: ""
		}, this.requestUser, setFunc);

		// 创建消息池
		msgPool = new _.pool(data.msgPool || {}, {
			id: "加载中...",
			type: "加载中...",
			time: "加载中...",
			unRead: "加载中...",
			sendID: "加载中...",
			message: "加载中...",
			receiveID: "加载中..."
		}, this.requestMsg, setFunc);

		msgPool.delModel = function(pool, id)
		{
			pool.id = null;
		}

		pubList = data.publicList || [];
		priMsg = data.privateMsg || {};
		proList = data.protectedList || [];

		Lyx.extend(this.callback, callback);
    }

    Lyx.p2t(msg, {
		onopen: function()
		{
			console.log("onopen......");
		},
		onmessage: function(event)
		{
			var data = JSON.parse(event.data);
			if(this.open || data.type === "open")
			{
				this.callback[json.type](data);
			}
			else
			{
				receiveList.enqueue(data);
			}
			log("onmessage......");
		},
		onclose: function()
		{
			log("onclose..........");
			time = "";
			status = false;
		},

		login: function(username, password, imgCode, callback)
		{
			var request = {
				method: "post",
				url: "forum/login_webAjaxCheck.lyx",
				data: {
					username: username,
					password: password,
					imgCode: imgCode
				}
			}
			ajax(request, function(xhr, response){
				callback(response);
				if(response != "验证码错误" && response != "用户不存在或者密码错误")
				{
					try
					{
						var json = JSON.parse(response);
						user.ID = json.ID;
						user.name = json.name;

						// 打开websocket连接
						ui.websocket.call(this, "ws://"+ window.location.host + "/" + "forum/message");
					}
					catch(error){}
				}
			});
		},

		// 注销
		logout: function()
		{
			ajax({
				method: "post",
				url: "forum/login_webAjaxExit.lyx"
			}, function(){
				user.name = "";
				status = false;
				callback && callback();
			});
		},

		// 从用户池中获取用户信息
		getUser: function(id)
		{
			return userPool.getId(id);
		},

		// 向服务器请求用户信息
		requestUser: function(idList)
		{
			this.send({
				type: "getUser",
				idList: idList
			});
		},

		// 向服务器请求消息
		requestMsg: function()
		{
			this.send({
				type: "getMsg",
				idList: idList
			});
		},

		// 获取当前登录人信息
		getUserInfo: function()
		{
			this.send({
				type: "stuInfo"
			});
		},

		// 发送私聊信息
		sendMsg: function(receiveID, content)
		{
			if(content.length == 0)
			{
				return "消息不可为空！";
			}
			else if(content.length > 6000)
			{
				return "消息过长！";
			}
			else
			{
				ws.send({
					type: "msg",
					ID: receiveID,
					content: content
				});
			}
			return true;
		},

		// 获取更多消息
		getMoreMsg: function(type, page, id)
		{
			var msg = {
				page: page,
				time: time
			};
			switch(type)
			{
				case "public":
					msg.id = id;
					msg.type = "morePub";
					break;
				case "protected":
					msg.type = "morePro";
					if(proPage == "noMore")
					{
						receipt.morePro(false);
						return false;
					}
					msg.page = proPage;
					break;
				case "private":
					msg.ID = id;
					msg.type = "morePri";
					break;
			}
			this.send(msg);
			return true;
		},

		// 更新用户信息
		updata: function(nickname, birth)
		{
			var regex = /^[A-Za-z0-9/_\-\u4e00-\u9fa5]{3,10}$/;
			if(nickname != "" && regex.test(nickname))
			{
				ws.send({
					type: "updata",
					name: nickname,
					birth: birth
				});
				return true;
			}
			else
			{
				return "昵称最少3个字符最多10个字符，不可包含特殊符号";
			}
		},

		// 标记id对应信息已读
		read: function(id)
		{
			this.send({
				id: id,
				type: "read"
			});
		},

		// 删除消息
		delMsg: function(id)
		{
			// 后台根据id计算消息类型，返回时附带type
			this.send({
				id: id,
				type: "del"
			});
		},

		// 获取以当前时间节点为基准的第一页评论
		getComment: function(id)
		{
			ws.send({
				id: id,
				type: "getComment"
			});
		},

		// 更新评论
		getNewComment: function(id, time)
		{
			ws.send({
				id: id,
				time: time,
				type: "newComment"
			});
		},

		// 提交评论
		comment: function(id, msg)
		{
			if(msg.trim() == "")
			{
				return "内容不能为空！";
			}
			else if(stringLength(msg)/2 > 144)
			{
				return "最多评论144个字！";
			}
			else
			{
				ws.send({
					id: id,
					msg: msg,
					type: "comment"
				});
				return true;
			}
		},

		callback: {
			msg: function(json)
			{
				for(var i = 0; i < json.list.length; i++)
				{
					var msg = json.list[i];
					msg.unRead = msg.unRead == 1;
					msg.sendID = ub.setList(msg.sendID);
					msg.receiveID = ub.setList(msg.receiveID);
					msgClassify[msg.type](msg);
					setFunc(msgList, msg.id, msg);
					if(new Date(msg.time) - new Date(time) >= 0 && msg.sendID != ID)
					{
						self.onNewMsg(msg);
					}
					receipt.msg || receipt.msg(msg);
				}
				ub.sendList();
			},
			online: function(json)
			{
				for(i in json.online)
				{
					if(typeof userList[i] != "undefined")
					{
						userList[i].online = json.online[i];
					}
				}
			},
			getMsg: function(json)
			{
				mb.setModel(json.map);
			},
			getUser: function(json)
			{
				ub.setModel(json.map);
			},
			open: function(json)
			{
				if(ID != json.ID)
				{
					ws.close();
					return;
				}
				open = true;
				status = true;
				time = json.time;
				while(receiveList.length != 0)
				{
					var json = receiveList.pop();
					call[json.type](json, self);
				}
			},
			del: function(json)
			{
				if(json.idList)
				{
					for(var i = 0; i < json.idList; i ++)
					{
						mb.del(json.idList[i]);
					}
					receipt.delPub(json);
				}
				else
				{
					mb.del(json.id);
					for(var i = 0; i < proList.lenght; i ++)
					{
						if(json.id == proList[i].message.id)
						{
							proList.splice(i, 1);
						}
					}
					receipt.delPro(json);
				}
			},
			morePro: function(json)
			{
				if(json.page)
				{
					proPage ++;
				}
				else
				{
					proPage = "noMore";
				}
				receipt.morePro = receipt.morePro || function(){};
				receipt.morePro(json.page != "noMore");
			},
			conflict: function()
			{
				alert("该用户在其他地方登陆！");
			}
		}
    });

    Lyx.inherits(ui.websocket, msg);

    return function(callback, data, setFunc)
    {
        return new msg(callback, data, setFunc);
    }
});